﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.IO;
using System.Linq;
using System.Runtime.Serialization;
using System.Runtime.Serialization.Formatters.Binary;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Markup;
using System.Xml;
using System.Xml.Serialization;

namespace VisualMusic
{
    public enum VisualDirection
    {
        Up,
        Down,
        Left,
        Right,
    }

    public class Setting : INotifyPropertyChanged
    {
        private string _name = "默认";
        private int _samplingStart = 0;
        private int _samplingEnd = 10;
        private VisualDirection _direction = VisualDirection.Up;
        private float _width = 1;
        private float _height = 1;
        private float _centerX = 0.5f;
        private float _centerY = 0.9f;
        private bool _isTowWay = false;
        private bool _isGradient = true;
        private int _colorA = 0xfe;
        private int _colorR = 0x66;
        private int _colorG = 0xcc;
        private int _colorB = 0xff;
        private int _hueStart = 0;
        private int _hueEnd = 360;
        private byte _saturation = 70;
        private byte _brightness = 100;
        private int _lineCount = 300;
        private float _lineWidth = 0.5f;
        private bool _corners = true;
        private float _gain = 500;
        private float _attenuation = 0.8f;
        private float _attenuationThreshold = 10;

        public string Name { get => _name; set => setValue(ref _name, value, nameof(Name)); }
        public int SamplingStart { get => _samplingStart; set => setValue(ref _samplingStart, value, nameof(SamplingStart)); }
        public int SamplingEnd { get => _samplingStart; set => setValue(ref _samplingEnd, value, nameof(SamplingEnd)); }
        public VisualDirection Direction { get => _direction; set => setValue(ref _direction, value, nameof(Direction)); }
        public float Width { get => _width; set => setValue(ref _width, value, nameof(Width)); }
        public float Height { get => _height; set => setValue(ref _height, value, nameof(Height)); }
        public float CenterX { get => _centerX; set => setValue(ref _centerX, value, nameof(CenterX)); }
        public float CenterY { get => _centerY; set => setValue(ref _centerY, value, nameof(CenterY)); }
        public bool IsTowWay { get => _isTowWay; set => setValue(ref _isTowWay, value, nameof(IsTowWay)); }
        public bool IsGradient
        {
            get => _isGradient;
            set
            {
                setValue(ref _isGradient, value, nameof(IsGradient));
                OnReload();
            }
        }
        public int ColorA
        {
            get => _colorA;
            set
            {
                setValue(ref _colorA, value, nameof(ColorA));
                OnReload();
            }
        }
        public int ColorR
        {
            get => _colorR; set
            {
                setValue(ref _colorR, value, nameof(ColorR));
                OnReload();
            }
        }
        public int ColorG
        {
            get => _colorG; 
            set
            {
                setValue(ref _colorG, value, nameof(ColorG));
                OnReload();
            }
        }
        public int ColorB
        {
            get => _colorB;
            set
            {
                setValue(ref _colorB, value, nameof(ColorB));
                OnReload();
            }
        }
        public int HueStart
        {
            get => _hueStart; 
            set
            {
                setValue(ref _hueStart, value, nameof(HueStart));
                OnReload();
            }
        }
        public int HueEnd
        {
            get => _hueEnd; 
            set
            {
                setValue(ref _hueEnd, value, nameof(HueEnd));
                OnReload();
            }
        }
        public byte Saturation
        {
            get => _saturation;
            set
            {
                setValue(ref _saturation, value, nameof(Saturation));
                OnReload();
            }
        }
        public byte Brightness
        {
            get => _brightness; 
            set
            {
                setValue(ref _brightness, value, nameof(Brightness));
                OnReload();
            }
        }
        public int LineCount
        {
            get => _lineCount;
            set
            {
                setValue(ref _lineCount, value, nameof(LineCount));
                OnReload();
            }
        }
        public float LineWidth { get => _lineWidth; set => setValue(ref _lineWidth, value, nameof(LineWidth)); }
        public bool Corners { get => _corners; set => setValue(ref _corners, value, nameof(Corners)); }
        public float Gain { get => _gain; set => setValue(ref _gain, value, nameof(Gain)); }
        public float Attenuation { get => _attenuation; set => setValue(ref _attenuation, value, nameof(Attenuation)); }
        public float AttenuationThreshold { get => _attenuationThreshold; set => setValue(ref _attenuationThreshold, value, nameof(AttenuationThreshold)); }

        private void setValue<T>(ref T propertyName, T value, string fatherPropertyName)
        {
            propertyName = value;
            NotifyPropertyChanged(fatherPropertyName);
        }

        public event PropertyChangedEventHandler? PropertyChanged;
        public void NotifyPropertyChanged(string propertyName)
        {
            if (this.PropertyChanged != null)
            {
                this.PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
            }
        }

        public delegate void ReLoad();
        public ReLoad OnReload = () => { };
    }
}
